package com.cssw.fyzb.busi.config;

import com.alibaba.fastjson.JSON;
import com.cssw.fyzb.busi.model.tps.*;
import com.cssw.fyzb.busi.util.BizUtil;
import com.ydn.appserver.ClientConfiguration;
import com.ydn.appserver.MinaAppClient;
import com.ydn.appserver.Request;
import com.ydn.appserver.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Feng Chen
 */
@Component
public class TpsClient {

    @Value("${tps.addrs}")
    private String addrs;

    @Value("${tps.maxConn:64}")
    private int maxConn;

    @Value("${tps.coTimeout:3000}")
    private int coTimeout;

    @Value("${tps.soTimeout:3000}")
    private int soTimeout;

    private MinaAppClient delegate;

    @PostConstruct
    public void start() {
        ClientConfiguration configuration = new ClientConfiguration();
        configuration.setServerAddressesString(addrs);
        configuration.setMaxConnectionsPerServer(maxConn);
        configuration.setSocketConnTimeoutSec(coTimeout);
        configuration.setSocketDataTimeoutSec(soTimeout);
        delegate = new MinaAppClient(configuration);
    }

    @PreDestroy
    public void close() {
        if (delegate != null) {
            delegate.close();
        }
    }

    /**
     * 传化快捷签约
     *
     * @return
     */
    public Tf56PayQuickSignVo tf56PayQuickSign(String cardNo, String realName, String idCard, String mobile, String orderNo, Long userId) {
        Map<String, Object> param = new HashMap<>();
        param.put("cardNo", cardNo);
        param.put("realName", realName);
        param.put("idCard", idCard);
        param.put("mobile", mobile);
        param.put("orderNo", orderNo);
        param.put("userId", userId);

        return getByBusi("Tf56PayQuickSign", param, Tf56PayQuickSignVo.class);
    }

    /**
     * 传化快捷签约
     *
     * @return
     */
    public Tf56PayQuickSignSmsVo tf56PayQuickSignSmsOk(String busiNo, String verifyCode) {
        Map<String, Object> param = new HashMap<>();
        param.put("busiNo", busiNo);
        param.put("verifyCode", verifyCode);
        return getByBusi("Tf56PayQuickSignSmsOk", param, Tf56PayQuickSignSmsVo.class);
    }

    /**
     * 传化快捷支付
     *
     * @return
     */
    public Tf56PayQuickPayVo tf56PayQuickPay(String goodsName, String amount, String certCode, String orderNo, Long userId, String description) {
        Map<String, Object> param = new HashMap<>();
        param.put("goodsName", goodsName);
        param.put("amount", amount);
        param.put("certCode", certCode);
        param.put("orderNo", orderNo);
        param.put("userId", userId);
        param.put("description", description);

        return getByBusi("Tf56PayQuickPay", param, Tf56PayQuickPayVo.class);
    }


    /**
     * 传化快捷支付
     *
     * @return
     */
    public Tf56PayQuickPaySmsVo tf56PayQuickPaySms(String busiNo, String verifyCode) {
        Map<String, Object> param = new HashMap<>();
        param.put("busiNo", busiNo);
        param.put("verifyCode", verifyCode);

        return getByBusi("Tf56PayQuickPaySmsConfirm", param, Tf56PayQuickPaySmsVo.class);
    }

    /**
     * 经纬度转地址
     *
     * @param lat 维度
     * @param lng 经度
     * @return
     */
    public Address getAddress(String lat, String lng) {
        Map<String, Object> param = new HashMap<>();
        param.put("lat", lat);
        param.put("lng", lng);
        return get("GetAddress", param, Address.class);
    }

    /**
     * 经纬度转地址
     *
     * @param media 视频地址
     * @param cover 封面地址
     * @return
     */
    public UploadVod uploadVod(String media, String cover) {
        Map<String, Object> param = new HashMap<>();
        param.put("media", media);
        param.put("cover", cover);
        return get("UploadVod", param, UploadVod.class);
    }

    /**
     * 获取上传签名
     *
     * @return
     */
    public UploadSigVo getUploadSig() {
        return get("GetUploadSig", null, UploadSigVo.class);
    }


    /**
     * 发送群定制消息
     *
     * @param liveId
     * @param data
     */
    public void sendGroupCustomMsg(Long liveId, Map<String, Object> data) {
        Request request = new Request("SendGroupCustomMsg");
        request.setParameter("groupId", liveId);
        request.setParameter("data", JSON.toJSONString(data));

        send(request);
    }

    /**
     * 创建直播流
     *
     * @param app    推流路径
     * @param stream 流名称
     * @param hour   直播时长(单位小时，默认24小时)
     * @return
     */
    public LiveStream createLiveStream(String app, String stream, Integer hour) {
        Map<String, Object> param = new HashMap<>();
        param.put("app", app);
        param.put("stream", stream);
        param.put("hour", hour);
        return get("CreateLiveStream", param, LiveStream.class);
    }


    public Response importAccount(Long userId, String nickName, String avatar) {
        Request request = new Request("AccountImport");
        request.setParameter("identifier", userId);
        request.setParameter("nick", nickName);
        request.setParameter("faceUrl", avatar);
        return send(request);
    }

    /**
     * 退出直播流
     *
     * @param app    推流路径
     * @param stream 流名称
     * @return
     */
    public OptLiveStream dropLiveStream(String app, String stream) {
        Map<String, Object> param = new HashMap<>();
        param.put("app", app);
        param.put("stream", stream);
        return get("DropLiveStream", param, OptLiveStream.class);
    }

    /**
     * 禁止直播流
     *
     * @param app    推流路径
     * @param stream 流名称
     * @return
     */
    public OptLiveStream forbidLiveStream(String app, String stream) {
        Map<String, Object> param = new HashMap<>();
        param.put("app", app);
        param.put("stream", stream);
        return get("ForbidLiveStream", param, OptLiveStream.class);
    }

    /**
     * 恢复直播流
     *
     * @param app    推流路径
     * @param stream 流名称
     * @return
     */
    public OptLiveStream resumeLiveStream(String app, String stream) {
        Map<String, Object> param = new HashMap<>();
        param.put("app", app);
        param.put("stream", stream);
        return get("ResumeLiveStream", param, OptLiveStream.class);
    }


    /**
     * 创建混流
     *
     * @param liveId
     * @param stream
     * @param params
     * @return
     */
    public OptLiveStream createMixLiveStream(String liveId, String stream, String params) {
        Map<String, Object> param = new HashMap<>();
        param.put("liveId", liveId);
        param.put("stream", stream);
        param.put("params", params);
        return get("CreateMixLiveStream", param, OptLiveStream.class);
    }

    /**
     * 取消混流
     *
     * @param liveId
     * @return
     */
    public OptLiveStream cancelMixLiveStream(String liveId) {
        Map<String, Object> param = new HashMap<>();
        param.put("liveId", liveId);
        return get("CancelMixLiveStream", param, OptLiveStream.class);
    }

    private <T> T get(String action, Map<String, Object> params, Class<T> type) {
        Request request = new Request(action);
        if (params != null) {
            for (Map.Entry<String, Object> param : params.entrySet()) {
                Object value = param.getValue();
                if (value != null) {
                    request.setParameter(param.getKey(), String.valueOf(value));
                }
            }
        }
        Response response = delegate.send(request);
        if (response.isSuccess()) {
            return response.getObject("data", type);
        }
        return null;
    }

    private <T> T getByBusi(String action, Map<String, Object> params, Class<T> type) {
        Request request = new Request(action);
        if (params != null) {
            for (Map.Entry<String, Object> param : params.entrySet()) {
                Object value = param.getValue();
                if (value != null) {
                    request.setParameter(param.getKey(), String.valueOf(value));
                }
            }
        }
        Response response = delegate.send(request);
        if (response.isSuccess()) {
            return response.getObject("data", type);
        } else {
            BizUtil.exception(response.getCode(), response.getMessage());
        }
        return null;
    }

    private <T> Page<T> page(String action, Map<String, Object> params, Class<T> type) {
        Request request = new Request(action);
        for (Map.Entry<String, Object> param : params.entrySet()) {
            Object value = param.getValue();
            if (value != null) {
                request.setParameter(param.getKey(), String.valueOf(value));
            }
        }
        Response response = delegate.send(request);
        if (response.isSuccess()) {
            Page<T> page = new Page<>();
            Integer total = response.getInteger("total");
            if (total == null) {
                total = 0;
            }
            Integer count = response.getInteger("count");
            if (count == null) {
                count = 0;
            }

            page.setTotal(total);
            page.setCount(count);
            page.setList(response.getList("list", type));
            return page;
        }

        return null;
    }

    public Response send(Request request) {
        return delegate.send(request);
    }

}
